package com.xyz.code.bean;

import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.xyz.code.util.Constants;
import com.xyz.code.util.JavaBeanUtil;
import com.xyz.code.util.JdbcUtils;
import com.xyz.code.util.PropertiesUtil;

public class MetaDataBean {

	private String tableName;

	private String className;

	private String entityName;

	private String basePackage;

	public String packagePath;
	public String entityPackage;
	public String facadePackage;
	public String repoPackage;
	public String servicePackage;

	public String shardingBean;

	public String getEntityPackage() {
		return entityPackage;
	}

	public void setEntityPackage(String entityPackage) {
		this.entityPackage = entityPackage;
	}

	public String getFacadePackage() {
		return facadePackage;
	}

	public void setFacadePackage(String facadePackage) {
		this.facadePackage = facadePackage;
	}

	public String getRepoPackage() {
		return repoPackage;
	}

	public void setRepoPackage(String repoPackage) {
		this.repoPackage = repoPackage;
	}

	public String getServicePackage() {
		return servicePackage;
	}

	public void setServicePackage(String servicePackage) {
		this.servicePackage = servicePackage;
	}

	public String getPackagePath() {
		return packagePath;
	}

	public void setPackagePath(String packagePath) {
		this.packagePath = packagePath;
	}

	private String outFileName;

	public String getOutFileName() {
		return outFileName;
	}

	public void setOutFileName(String outFileName) {
		this.outFileName = outFileName;
	}

	private String zxPackage; // 中心路径

	private String modName; // 模块名

	private String serviceBean;// Service层Bean名
	private String facadeBean;// Facade层名

	private String extEntityBaseClassName; // entity基类名
	private String extEntityBaseClassNamePackage; // entity基类包名

	private String dtoBaseClassName; // dto基类
	private String dtoBaseClassPackage; // dto基类报名

	private String extVoBaseClassName; // vo基类名
	private String extVoBaseClassNamePackage; // vo基类包名

	private String extIServiceBaseClassName; // service基类接口
	private String extIServiceBaseClassNamePackage; // service基类接口包名

	private String extServiceBaseImplClassName; // service基类实现类
	private String extServiceBaseImplClassNamePackage; // service基类实现类包名

	private String extIRepositoryBaseClassName; // repository基类接口
	private String extIRepositoryBaseClassNamePackage; // repository基类接口类包名

	private String extRepositoryBaseImplClassName; // repository基类实现
	private String extRepositoryBaseImplClassNamePackage; // repository基类实现类包名

	private String extIFacadeBaseClassName; // facade基类接口
	private String extIFacadeBaseClassNamePackage; // facade基类接口类包名

	private String extFacadeBaseImplClassName; // facade基类实现
	private String extFacadeBaseImplClassNamePackage; // facade基类实现类包名

	private String shardingColumnName; // 分片键字段名

	public String getShardingColumnName() {
		return shardingColumnName;
	}

	public void setShardingColumnName(String shardingColumnName) {
		this.shardingColumnName = shardingColumnName;
	}

	private AttrInfo pkAttrInfo; // service基类

	private List<AttrInfo> attrInfos = new ArrayList<AttrInfo>();

	private Map<String, AttrInfo> attrMap = new HashMap<String, AttrInfo>();

	public String getTableName() {
		return tableName.toUpperCase();
	}

	public void setTableName(String tableName) {
		this.tableName = tableName;
	}

	public String getBasePackage() {
		return basePackage;
	}

	public void setBasePackage(String basePackage) {
		this.basePackage = basePackage;
	}

	public String getClassName() {
		return JavaBeanUtil.toCamelCaseString(className, true);
	}

	public void setClassName(String className) {
		this.className = className;
	}

	public String getEntityName() {
		return JavaBeanUtil.toCamelCaseString(entityName, false);
	}

	public void setEntityName(String entityName) {
		this.entityName = entityName;
	}

	public AttrInfo getPkAttrInfo() {
		return pkAttrInfo;
	}

	public void setPkAttrInfo(AttrInfo pkAttrInfo) {
		this.pkAttrInfo = pkAttrInfo;
	}

	public List<AttrInfo> getAttrInfos() {
		return attrInfos;
	}

	public void setAttrInfos(List<AttrInfo> attrInfos) {
		this.attrInfos = attrInfos;
	}

	public String getShardingBean() {
		return shardingBean;
	}

	public void setShardingBean(String shardingBean) {
		this.shardingBean = shardingBean;
	}

	public MetaDataBean(String tableName, String packagePath,
			String outFileName, Map<String, String> map) {
		this.tableName = tableName;
		this.packagePath = packagePath;
		this.entityPackage = map.get("entityPackagePath");
		this.facadePackage = map.get("ifacadePackagePath");
		this.repoPackage = map.get("irepPackagePath");
		this.servicePackage = map.get("iserPackagePath");
		// this.basePackage = packageName;
		this.outFileName = outFileName;
		// int i = basePackage.lastIndexOf(".");
		// this.zxPackage = basePackage.substring(0, i);
		// this.modName = StringUtils.first2Upper(basePackage.substring(i + 1));
		tableName = tableName.toUpperCase();
		Pattern pattern = Pattern.compile("^[A-Z]{2}\\_");
		Matcher matcher = pattern.matcher(tableName);

		boolean find = false;
		while (matcher.find()) {
			find = true;
			String temp = tableName.substring(matcher.start(), matcher.end());
			tableName = tableName.replaceAll(temp, "");
			matcher = pattern.matcher(tableName);
		}

		if (!find) {
			String prefixTableNames = PropertiesUtil.getConfigValueCache(
					Constants.CONFIG_FILE, Constants.FTABLENAME);
			for (String s : prefixTableNames.toUpperCase().split(",")) {
				if (tableName.startsWith(s)) {
					tableName = tableName.replace(s, "");
					break;
				}
			}
		}
		// 获取分片键字段名配置
		this.shardingColumnName = PropertiesUtil.getConfigValueCache(
				Constants.CONFIG_FILE, Constants.SHARDING_COLUMN_NAME);
		this.setEntityName(tableName);
		this.setClassName(tableName);
		createMetaInfo();
		// 校验是否存在分片键
		boolean is = false;
		if (attrInfos != null && attrInfos.size() > 0) {
			for (AttrInfo a : attrInfos) {
				if (a.getColumnName().equals(shardingColumnName)) {
					is = true;
					break;
				}
			}
			if (is) {
				this.setShardingBean("@ShardingBean");
			} else {
				this.setShardingBean("");
			}
		}
	}

	public void createMetaInfo() {
		Connection conn = null; // 得到数据库连接
		try {
			conn = JdbcUtils.getInstance().getServerConnection();
			DatabaseMetaData dmd = conn.getMetaData();
			ResultSet set2 = dmd.getColumns(null, null, tableName, null);
			while (set2.next()) {
				AttrInfo info = new AttrInfo();
				info.setColumnName(set2.getString("COLUMN_NAME").toUpperCase());
				info.setDbType(set2.getString("TYPE_NAME"));
				info.setComment(set2.getString("REMARKS") != null
						? set2.getString("REMARKS") : "");
				attrMap.put(info.getColumnName(), info);
			}
			ResultSet set = conn.getMetaData().getPrimaryKeys(null, null,
					tableName);
			if (set.next()) {
				String column = set.getString("COLUMN_NAME").toUpperCase();
				pkAttrInfo = attrMap.remove(column);
			}

			attrInfos = new ArrayList<AttrInfo>(attrMap.values());
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			JdbcUtils.free(conn, null, null);
		}
	}

	public static void main(String[] args) {
		// MetaDataBean bean = new MetaDataBean("PZ_GG_SERVICE_OFFER",
		// "com.ctg.itrdc.product","",);
		// bean.createMetaInfo();
		// System.out.println(bean.getClassName());
		// System.out.println(bean.getPkAttrInfo());
		// System.out.println(bean.getAttrInfos());
	}

	public String getZxPackage() {
		return zxPackage;
	}

	public void setZxPackage(String zxPackage) {
		this.zxPackage = zxPackage;
	}

	public String getModName() {
		return modName;
	}

	public void setModName(String modName) {
		this.modName = modName;
	}

	/**
	 * @return the serviceBean
	 */
	public String getServiceBean() {
		String serviceName = JavaBeanUtil.toCamelCaseString(this.getClassName(),
				false);
		this.serviceBean = serviceName + "Service";
		return serviceBean;
	}

	/**
	 * @return the facadeBean
	 */
	public String getFacadeBean() {
		String serviceName = JavaBeanUtil.toCamelCaseString(this.getClassName(),
				false);
		this.facadeBean = serviceName + "Facade";
		return facadeBean;
	}

	public String getExtEntityBaseClassName() {
		String entityBaseClassName = PropertiesUtil.getConfigValueCache(
				Constants.CONFIG_FILE, Constants.ENTITY_BASE_CLASSNAME);
		this.extEntityBaseClassName = entityBaseClassName;
		return entityBaseClassName;
	}

	public String getExtVoBaseClassName() {
		String voBaseClassName = PropertiesUtil.getConfigValueCache(
				Constants.CONFIG_FILE, Constants.VO_BASE_CLASSNAME);
		this.extVoBaseClassName = voBaseClassName;
		return voBaseClassName;
	}

	public String getExtIServiceBaseClassName() {
		String serviceBaseClassName = PropertiesUtil.getConfigValueCache(
				Constants.CONFIG_FILE, Constants.ISERVICE_BASE_CLASSNAME);
		this.extIServiceBaseClassName = serviceBaseClassName;
		return serviceBaseClassName;
	}

	public String getExtServiceBaseImplClassName() {
		String serviceBaseClassName = PropertiesUtil.getConfigValueCache(
				Constants.CONFIG_FILE, Constants.SERVICE_BASE_IMPL_CLASSNAME);
		this.extServiceBaseImplClassName = serviceBaseClassName;
		return serviceBaseClassName;
	}

	public String getExtIRepositoryBaseClassName() {
		String repositoryBaseClassName = PropertiesUtil.getConfigValueCache(
				Constants.CONFIG_FILE, Constants.IREPOSITORY_BASE_CLASSNAME);
		this.extIRepositoryBaseClassName = repositoryBaseClassName;
		return repositoryBaseClassName;
	}

	public String getExtRepositoryBaseImplClassName() {
		String repositoryBaseClassName = PropertiesUtil.getConfigValueCache(
				Constants.CONFIG_FILE,
				Constants.REPOSITORY_BASE_IMPL_CLASSNAME);
		this.extRepositoryBaseImplClassName = repositoryBaseClassName;
		return repositoryBaseClassName;
	}

	public String getExtIFacadeBaseClassName() {
		String facadeBaseClassName = PropertiesUtil.getConfigValueCache(
				Constants.CONFIG_FILE, Constants.IFACADE_BASE_CLASSNAME);
		this.extIFacadeBaseClassName = facadeBaseClassName;
		return facadeBaseClassName;
	}

	public String getExtFacadeBaseImplClassName() {
		String facadeBaseClassName = PropertiesUtil.getConfigValueCache(
				Constants.CONFIG_FILE, Constants.FACADE_BASE_IMPL_CLASSNAME);
		this.extFacadeBaseImplClassName = facadeBaseClassName;
		return facadeBaseClassName;
	}

	public String getExtEntityBaseClassNamePackage() {
		String entityBaseClassNamePackage = PropertiesUtil.getConfigValueCache(
				Constants.CONFIG_FILE, Constants.ENTITY_BASE_CLASSNAME_PACKAGE);
		this.extEntityBaseClassNamePackage = entityBaseClassNamePackage;
		return entityBaseClassNamePackage;
	}

	public String getExtVoBaseClassNamePackage() {
		String voBaseClassNamePackage = PropertiesUtil.getConfigValueCache(
				Constants.CONFIG_FILE, Constants.VO_BASE_CLASSNAME_PACKAGE);
		this.extVoBaseClassNamePackage = voBaseClassNamePackage;
		return voBaseClassNamePackage;
	}

	public String getExtIServiceBaseClassNamePackage() {
		String iServiceBaseClassNamePackage = PropertiesUtil
				.getConfigValueCache(Constants.CONFIG_FILE,
						Constants.ISERVICE_BASE_CLASSNAME_PACKAGE);
		this.extIServiceBaseClassNamePackage = iServiceBaseClassNamePackage;
		return iServiceBaseClassNamePackage;
	}

	public String getExtServiceBaseImplClassNamePackage() {
		String serviceBaseImplClassNamePackage = PropertiesUtil
				.getConfigValueCache(Constants.CONFIG_FILE,
						Constants.SERVICE_BASE_IMPL_CLASSNAME_PACKAGE);
		this.extServiceBaseImplClassNamePackage = serviceBaseImplClassNamePackage;
		return serviceBaseImplClassNamePackage;
	}

	public String getExtIRepositoryBaseClassNamePackage() {
		String iRepositoryBaseClassNamePackage = PropertiesUtil
				.getConfigValueCache(Constants.CONFIG_FILE,
						Constants.IREPOSITORY_BASE_CLASSNAME_PACKAGE);
		this.extIRepositoryBaseClassNamePackage = iRepositoryBaseClassNamePackage;
		return iRepositoryBaseClassNamePackage;
	}

	public String getExtRepositoryBaseImplClassNamePackage() {
		String repositoryBaseImplClassNamePackage = PropertiesUtil
				.getConfigValueCache(Constants.CONFIG_FILE,
						Constants.REPOSITORY_BASE_IMPL_CLASSNAME_PACKAGE);
		this.extRepositoryBaseImplClassNamePackage = repositoryBaseImplClassNamePackage;
		return repositoryBaseImplClassNamePackage;
	}

	public String getExtIFacadeBaseClassNamePackage() {
		String iFacadeBaseClassNamePackage = PropertiesUtil.getConfigValueCache(
				Constants.CONFIG_FILE,
				Constants.IFACADE_BASE_CLASSNAME_PACKAGE);
		this.extIFacadeBaseClassNamePackage = iFacadeBaseClassNamePackage;
		return iFacadeBaseClassNamePackage;
	}

	public String getExtFacadeBaseImplClassNamePackage() {
		String facadeBaseImplClassNamePackage = PropertiesUtil
				.getConfigValueCache(Constants.CONFIG_FILE,
						Constants.FACADE_BASE_IMPL_CLASSNAME_PACKAGE);
		this.extFacadeBaseImplClassNamePackage = facadeBaseImplClassNamePackage;
		return facadeBaseImplClassNamePackage;
	}

	public String getDtoBaseClassName() {
		String dtoBaseClassName = PropertiesUtil.getConfigValueCache(
				Constants.CONFIG_FILE, Constants.DTO_BASE_CLASSNAME);
		this.dtoBaseClassName = dtoBaseClassName;
		return dtoBaseClassName;
	}

	public String getDtoBaseClassPackage() {
		String dtoBaseClassPackage = PropertiesUtil.getConfigValueCache(
				Constants.CONFIG_FILE, Constants.DTO_BASE_CLASSNAME_PACKAGE);
		this.dtoBaseClassPackage = dtoBaseClassPackage;
		return dtoBaseClassPackage;
	}

}
